﻿using System.Globalization;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;


namespace LoD.WPClientLibrary.Controls {
    public class HSlider : GuiControl {
        private readonly Sprite _sprBar;
        private readonly Sprite _sprLeftEnd;
        private readonly Sprite _sprRightEnd;
        private int _limit;
        private int _value;

        public HSlider(ContentManager content, SpriteBatch spriteBatch, SpriteFont font)
            : base(content, spriteBatch, font) {
            Scale = 1.0f;
            this.Start = Vector2.Zero;

            // ReSharper disable DoNotCallOverridableMethodsInConstructor
            Load("Controls/slider_tab");
            // ReSharper restore DoNotCallOverridableMethodsInConstructor

            this._sprLeftEnd = new Sprite(content, spriteBatch);
            this._sprLeftEnd.Load("Controls/hslider_end");
            this._sprLeftEnd.Origin = new Vector2(3, 16);

            this._sprRightEnd = new Sprite(content, spriteBatch);
            this._sprRightEnd.Load("Controls/hslider_end");
            this._sprRightEnd.Origin = new Vector2(0, 16);

            this._sprBar = new Sprite(content, spriteBatch);
            this._sprBar.Load("Controls/hslider_bar");
            this._sprBar.Origin = new Vector2(0, 16);
            this.Limit = 100;
        }

        public bool Moving { get; set; }
        public Vector2 Start { get; set; }

        public int Value {
            get { return this._value; }
            set {
                this._value = value;
                if (this._value < 0) this._value = 0;
                if (this._value > this._limit) this._value = this._limit;
                Position = new Vector2(this.Start.X + this._value, Position.Y);
            }
        }

        public int Limit {
            get { return this._limit; }
            set {
                this._limit = value;
                this._sprBar.ScaleV = new Vector2((this._limit + Image.Width + 1), 1.0f);
            }
        }

        public override void Update(TouchLocation touch) {
            base.Update(touch);

            this.Moving = false;

            if (touch.State != TouchLocationState.Moved) return;
            Rectangle rect = Boundary();
            var point = new Point((int)touch.Position.X, (int)touch.Position.Y);
            if (!rect.Contains(point)) return;
            Vector2 relative = Vector2.Zero;
            relative.X = touch.Position.X - Position.X;
            Position = new Vector2(Position.X + relative.X, Position.Y);
            this.Value = (int)(Position.X - this.Start.X);
            if (Position.X < this.Start.X) Position = new Vector2(this.Start.X, Position.Y);
            else if (this._value > this._limit) Position = new Vector2(Position.X - relative.X, Position.Y);

            this.Moving = true;
        }

        public override void Draw() {
            //draw ends
            this._sprLeftEnd.Position = new Vector2(this.Start.X - 16, this.Start.Y);
            this._sprLeftEnd.Color = Color;
            this._sprLeftEnd.Draw();
            this._sprRightEnd.Position = new Vector2(this.Start.X + 16 + this._limit, this.Start.Y);
            this._sprRightEnd.Color = Color;
            this._sprRightEnd.Draw();

            //draw middle bar
            this._sprBar.Position = new Vector2(this.Start.X - 16, this.Start.Y);
            this._sprBar.Color = Color;
            this._sprBar.Draw();


            //draw sliding circle
            base.Draw();

            //draw value text
            Vector2 size = Font.MeasureString(this._value.ToString(CultureInfo.InvariantCulture));
            SpriteBatch.DrawString(Font, this._value.ToString(CultureInfo.InvariantCulture), Position, Color.Black,
                                   0.0f, new Vector2(size.X / 2, size.Y / 2), 0.6f, SpriteEffects.None, 1.0f);
        }

        public void SetStartPosition(Vector2 pos) {
            Position = pos;
            this.Start = pos;
        }
    }

    public class VSlider : GuiControl {
        private readonly Sprite _sprBar;
        private readonly Sprite _sprBottomEnd;
        private readonly Sprite _sprTopEnd;
        private int _limit;
        private int _value;

        public VSlider(ContentManager content, SpriteBatch spriteBatch, SpriteFont font)
            : base(content, spriteBatch, font) {
            Scale = 1.0f;
            this.Start = Vector2.Zero;

            // ReSharper disable DoNotCallOverridableMethodsInConstructor
            Load("Controls/slider_tab");
            // ReSharper restore DoNotCallOverridableMethodsInConstructor

            this._sprTopEnd = new Sprite(content, spriteBatch);
            this._sprTopEnd.Load("Controls/vslider_end");
            this._sprTopEnd.Origin = new Vector2(16, 3);

            this._sprBottomEnd = new Sprite(content, spriteBatch);
            this._sprBottomEnd.Load("Controls/vslider_end");
            this._sprBottomEnd.Origin = new Vector2(16, 0);

            this._sprBar = new Sprite(content, spriteBatch);
            this._sprBar.Load("Controls/vslider_bar");
            this._sprBar.Origin = new Vector2(16, 0);
            this.Limit = 100;
        }

        public bool Moving { get; set; }
        public Vector2 Start { get; set; }

        public int Value {
            get { return this._value; }
            set {
                this._value = value;
                if (this._value < 0) this._value = 0;
                if (this._value > this._limit) this._value = this._limit;
                Position = new Vector2(Position.X, this.Start.Y + this._value);
            }
        }

        public int Limit {
            get { return this._limit; }
            set {
                this._limit = value;
                this._sprBar.ScaleV = new Vector2(1.0f, (this._limit + Image.Height + 1));
            }
        }

        public override void Update(TouchLocation touch) {
            base.Update(touch);

            this.Moving = false;

            if (touch.State != TouchLocationState.Moved) return;
            Rectangle rect = Boundary();
            var point = new Point((int)touch.Position.X, (int)touch.Position.Y);
            if (!rect.Contains(point)) return;
            Vector2 relative = Vector2.Zero;
            relative.Y = touch.Position.Y - Position.Y;
            Position = new Vector2(Position.X, Position.Y + relative.Y);
            this.Value = (int)(Position.Y - this.Start.Y);

            if (Position.Y < this.Start.Y) Position = new Vector2(Position.X, this.Start.Y);
            else if (this._value > this._limit) Position = new Vector2(Position.X, Position.Y - relative.Y);

            this.Moving = true;
        }

        public override void Draw() {
            //draw ends
            this._sprTopEnd.Position = new Vector2(this.Start.X, this.Start.Y - 16);
            this._sprTopEnd.Color = Color;
            this._sprTopEnd.Draw();
            this._sprBottomEnd.Position = new Vector2(this.Start.X, this.Start.Y + 16 + this._limit);
            this._sprBottomEnd.Color = Color;
            this._sprBottomEnd.Draw();

            //draw middle bar
            this._sprBar.Position = new Vector2(this.Start.X, this.Start.Y - 16);
            this._sprBar.Color = Color;
            this._sprBar.Draw();


            //draw sliding circle
            base.Draw();

            //draw value text
            Vector2 size = Font.MeasureString(this._value.ToString(CultureInfo.InvariantCulture));
            SpriteBatch.DrawString(Font, this._value.ToString(CultureInfo.InvariantCulture), Position,
                                   Color.Black, 0.0f, new Vector2(size.X / 2, size.Y / 2), 0.6f,
                                   SpriteEffects.None, Zindex);
        }

        public void SetStartPosition(Vector2 pos) {
            Position = pos;
            this.Start = pos;
        }
    }
}